home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
castools.zip
/
FINDENTR.C
< prev
next >
Wrap
Text File
|
1990-02-02
|
6KB
|
190 lines
/*
FINDENTR.C Function PbFindFirstOrNext: finds a phonebook entry (individual
or group) based on its name.
INPUT: Phonebook structure, possibly memory space to hold the entry, and a
name string specification or record ID.
OUTPUT: If successful, a pointer to a phonebook entry structure holding the
requested entry, as well as the record ID of the next entry that matches
the same name string spec, if any.
*/
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <phonebk.h>
PBE * pascal PbFindFirstOrNext(PB *pb,
PBE *entry,
char *name,
int *recordID)
{
PBE *pbe;
char searchst[32], /* wildcard coded search string */
testst[32]; /* fetched and converted string from entry*/
PBEFIXED fixed_part, *result; /* for call to GetFixedPart() */
char *vbl_part = NULL; /* for holding the rest of entry */
size_t vbl_length; /* length of entry variable part */
int FirstFound = 0,
start, /* rid where search starts */
i, j, k, /* loop counters */
red; /* for return value of fread() */
int temperrno = 0; /* for saving aside Pberrno */
Pberrno = 0; /* Initially, always reset */
/* First, check params */
if ((pb == NULL) ||
(name == NULL) ||
(recordID == NULL)) {
Pberrno = INVALIDPARAMETER;
return(NULL);
}
if ((*recordID < -1) ||
(*recordID > 999)) {
Pberrno = INVALIDPARAMETER;
return(NULL);
}
/* Decide whether we're allocating the memory, or caller has provided */
if (!entry) {
if (!(pbe = (PBE *)calloc(1, sizeof(PBE)))) {
Pberrno = OUTOFMEM;
return(NULL);
}
if (!(pbe->fields = (char **)calloc(pb->header.fields,
sizeof(char *)))) {
Pberrno = OUTOFMEM;
goto error_out;
}
for (i=0; i<pb->header.fields; i++) {
if (!(pbe->fields[i] = (char *)calloc(60, sizeof(char)))) {
Pberrno = OUTOFMEM;
goto error_out;
}
}
/* Can't allocate the membership list yet: don't know how many members */
}
else {
pbe = entry;
}
/* Convert name parameter to internal search string */
strncpy(searchst, name, NAMELENGTH);
for (i=0; i<NAMELENGTH; i++) {
if (searchst[i] == '*') {
for (j=i; j<NAMELENGTH; j++) {
searchst[j] = '?';
}
searchst[j-1] = '\0';
break;
}
}
/* Decide where to start search: If a "FindFirst", start at top */
if (*recordID == -1) {
start = 0;
}
else {
start = *recordID;
}
for (*recordID = start; *recordID < MAXENTRIES; (*recordID)++) {
result = GetFixedPart(pb, &fixed_part, *recordID);
if (result) {
strncpy(testst, fixed_part.name, NAMELENGTH);
for (i=0; i<NAMELENGTH; i++) {
if (searchst[i] == '?') {
testst[i] = '?';
}
}
/* Compare the two strings */
if (!(strnicmp(searchst, testst, NAMELENGTH))) { /* they match */
if (FirstFound) {
break;
}
else {
/* Set flag (found 1); copy fixed part, and allocate for members */
FirstFound = 1;
memcpy(pbe, &fixed_part, sizeof(PBEFIXED));
if (!entry) {
if (!(pbe->MemberList = (int *)malloc(pbe->members *
sizeof(int)))) {
Pberrno = OUTOFMEM;
goto error_out;
}
}
/* Read the rest of the entry into a buffer */
if (vbl_length = pbe->length - sizeof(PBEFIXED)) {
if (!(vbl_part = (char *)malloc(vbl_length))) {
Pberrno = OUTOFMEM;
goto error_out;
}
red = fread(vbl_part, 1, vbl_length, pb->fp);
if (red != vbl_length) {
Pberrno = CANTREAD;
goto error_out;
}
/* if read successful, fill in entry's variable fields */
if (pbe->type == PERSONENTRY) {
for (i=0, j=0; i<pb->header.fields; i++, j++) {
for (k=0; k<MAXFIELDSIZE; k++, j++) {
if (!(pbe->fields[i][k] = vbl_part[j])) {
break;
}
}
}
}
else {
j = 0;
}
for (i=0; i<pbe->members; i++) {
pbe->MemberList[i] = ((int *)(vbl_part + j))[i];
}
free(vbl_part);
}
}
} /* else: no match: just go on searching */
} /* else: no entry at that rid: just go on searching */
} /* end of searching: either found 2 or reached MAXENTRIES */
if (*recordID == MAXENTRIES) {
if (FirstFound) {
*recordID = -1;
Pberrno = NOMOREMATCH;
return(pbe); /* Not an error, but only found one */
}
else {
Pberrno = NOENTRYFOUND; /* Didn't find any */
goto error_out;
}
}
/* Not only found one, but a second */
return(pbe);
error_out:
if (vbl_part) {
free(vbl_part);
}
if (Pberrno) {
temperrno = Pberrno;
}
if (!entry) {
PbFreePBE(pb, pbe);
}
if (temperrno) {
Pberrno = temperrno;
}
return(NULL);
}